package com.ncloud.crm.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ncloud.crm.common.Constant;
import com.ncloud.crm.entity.*;
import com.ncloud.crm.entity.order.*;
import com.ncloud.crm.mapper.BsAttrMapper;
import com.ncloud.crm.service.*;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;

@Service
public class OrderFinishServiceImpl{
	
	private static final Logger logger = LogManager.getLogger(OrderFinishServiceImpl.class);
	
	@Autowired
	private OrderCustomerService custService;
	@Autowired
	private BsCustService bsCustService;
	@Autowired
	private OrderAccountService orderAcctService;
	@Autowired
	private BsAccountService bsAcctService;
	@Autowired
	private OrderProjectService orderProjectService;
	@Autowired
	private BsProjectService bsProjectService;
	@Autowired
	private OrderProductService orderProductService;
	@Autowired
	private BsProductService bsProductService;
	@Autowired
	private OrderDiscntService orderDiscntService;
	@Autowired
	private BsDiscntService bsDiscntService;
	@Autowired
	private WorkService workService;
	@Autowired
	private WorkNodeService workNodeService;
	@Autowired
	private BsNodeService bsNodeService;
	@Autowired
	private WorkNodeNetAccessService workNodeNetAccessService;
	@Autowired
	private BsNodeNetAccessService bsNodeNetAccessService;
	@Autowired
	private WorkNodeEqptService workNodeEqptService;
	@Autowired
	private BsNodeEqptService bsNodeEqptService;
	@Autowired
	private WorkNodeAttrService workNodeAttrService;
	@Autowired
	private BsNodeAttrService bsNodeAttrServvice;
	@Autowired
	private OrderService orderService;
	@Autowired
	private BsContractNodeService bsContractNodeService;
	@Autowired
	private WorkNodePublicCloudService workNodePublicCloudService;
	@Autowired
	private BsPublicCloudService bsPublicCloudService;
	@Autowired
	private OrderContractService orderContractService;
	@Autowired
	private BsContractService bsContractService;
	@Autowired
	private OrderAttrService orderAttrService;
	@Autowired
	private BsAttrMapper attrMapper;
	@Autowired
	private OrderDiscntFeeService orderDiscntFeeService;
	@Autowired
	private BsDiscntFeeService bsDiscntFeeService;
	@Autowired
	private WorkNodePublicCloudSegService workNodePublicCloudSegService;
	@Autowired
	private BsPublicCloudSegService bsPublicCloudSegService;
	@Transactional
	public JSONObject finishOrder(Long orderId) {
		//更新订单状态为完工
		Order order = new Order();
		order.setOrderId(orderId);
		order.setFinishTime(new Date());
		order.setOrderState(Constant.ORDER_STATE_DONE);
		orderService.updateOrderState(order);
		//处理账户资料落地
		finishOrderAccount(orderId);
		//处理项目信息落地
//		finishOrderProject(orderId);
		//处理项目产品信息落地
		finishOrderProduct(orderId);
		//处理资费信息落地
		finishOrderDiscnt(orderId);
		//处理合同信息落地
		finishOrderContract(orderId);
		//处理节点合同关系落地
		finishNodeContractRel(orderId);
		//处理套餐费用落地
		finishOrderDiscntFee(orderId);
		List<Work> works = workService.getWorksByOrderId(orderId);
		for (Work work : works) {
			//处理节点信息落地
			finishWorkNode(work);
			//处理节点接入信息落地
			finishWorkNodeNetAccess(work.getWorkId());
			//处理节点设备信息落地
			finishWorkEqpt(work.getWorkId());
			//处理公有云
			finishPublicCloud(work.getWorkId());
			//处理节点属性信息落地
			finishWorkNodeAttr(work.getWorkId());
			//处理云网段信息
			finishPublicCloudSeg(work.getWorkId());
		}
		//处理客户资料落地
		finishOrderCust(orderId);
		//把订单和工单表搬入历史表
		//moveOrder2His(orderId);
		//moveWork2His(orderId);
		
		return new JSONObject();
	}
	
	private void finishAttr(Long instId,String attrType) {
		logger.debug("处理属性信息开始"+instId);
		List<OrderAttr> orderAttrs = orderAttrService.getAttrsById(instId, attrType);
		for (OrderAttr orderAttr : orderAttrs) {
			BsAttr bsAttr = new BsAttr();
			BeanUtils.copyProperties(orderAttr, bsAttr);
			BsAttr resultAttr = attrMapper.getValidAttrInfo(bsAttr);
			if(resultAttr!=null && resultAttr.getAttrId() !=null){
				attrMapper.updateAttrValue(bsAttr);
			}else{
				attrMapper.insertOrderAttr(bsAttr);
			}

		}
		logger.debug("处理属性信息开始"+instId);
	}

	private void finishOrderDiscnt(Long orderId) {
		logger.debug("处理套餐信息开始"+orderId);
		List<OrderDiscnt> orderDiscnts = orderDiscntService.getByOrderId(orderId);
		for (OrderDiscnt orderDiscnt : orderDiscnts) {
			BsDiscnt discnt = new BsDiscnt();
			BeanUtils.copyProperties(orderDiscnt, discnt);
			switch (orderDiscnt.getModifyTag()) {
			case Constant.ADD:
				bsDiscntService.insertBsDiscnt(discnt);
				break;
			case Constant.UPDATE:
				bsDiscntService.updateBsDiscnt(discnt);
				break;
			case Constant.DEL:
				bsDiscntService.updateBsDiscnt(discnt);
				break;
			default:
				break;
			}
			//finishAttr(discnt.getDiscntInstId(), Constant.ATTR_TYPE_DISCNT);
		}
		logger.debug("处理套餐信息开始"+orderId);
	}

	private void finishPublicCloud(Long workId) {
		logger.debug("处理公有云信息开始"+workId);
		List<WorkNodePublicCloud> workNodePublicClouds = workNodePublicCloudService.getListByWorkId(workId);
		for (WorkNodePublicCloud workNodePublicCloud : workNodePublicClouds) {
			BsPublicCloud bsPublicCloud = new BsPublicCloud();
			BeanUtils.copyProperties(workNodePublicCloud, bsPublicCloud);
			switch (workNodePublicCloud.getModifyTag()) {
			case Constant.ADD:
				bsPublicCloudService.insertNodeCloud(bsPublicCloud);
				break;
			case Constant.UPDATE:
				bsPublicCloudService.updateNodeCloud(bsPublicCloud);
				break;
			case Constant.DEL:
				bsPublicCloudService.updateNodeCloud(bsPublicCloud);
				break;
			default:
				break;
			}
		}
		logger.debug("处理公有云信息开始"+workId);
	}

	private void finishNodeContractRel(Long orderId) {
		logger.debug("处理节点合同关系信息开始"+orderId);
		List<OrderContract> orderContracts = orderContractService.getByOrderId(orderId);
		List<WorkNode> workNodes = workNodeService.getNodesByOrderId(orderId);
		workNodes.removeIf(x->Constant.DEL.equals(x.getModifyTag()));
		for (OrderContract orderContract : orderContracts) {
			for (WorkNode workNode : workNodes) {
				BsContractNode contractNode=new BsContractNode();
				contractNode.setNodeId(workNode.getNodeId());
				contractNode.setContrInstId(orderContract.getContractId());
				contractNode.setBeginDate(workNode.getBeginDate());
				contractNode.setEndDate(workNode.getEndDate());
				contractNode.setUpdateTime(new Date());
				contractNode.setUpdateUser(workNode.getUpdateUser());
				bsContractNodeService.createContractNodeRel(contractNode);
			}
		}
		logger.debug("处理节点合同关系信息结束"+orderId);
	}

	private void moveWork2His(Long orderId) {
		workService.moveWork2His(orderId);
		workService.deleteByOrderId(orderId);
	}

	private void moveOrder2His(Long orderId) {
		orderService.moveOrder2His(orderId);
		orderService.deleteByOrderId(orderId);
	}

	private void finishWorkNodeAttr(long workId) {
		logger.debug("处理节点属性信息开始"+workId);
		List<WorkNodeAttr> nodeAttrs = workNodeAttrService.getNodeAttrsByWorkId(workId);
		for (WorkNodeAttr workNodeAttr : nodeAttrs) {
			BsNodeAttr nodeAttr = new BsNodeAttr();
			BeanUtils.copyProperties(workNodeAttr, nodeAttr);
			switch (workNodeAttr.getModifyTag()) {
			case Constant.ADD:
				bsNodeAttrServvice.insertNodeAttr(nodeAttr);
				break;
			case Constant.UPDATE:
				bsNodeAttrServvice.updateNodeAttr(nodeAttr);
				break;
			case Constant.DEL:
				bsNodeAttrServvice.updateNodeAttr(nodeAttr);
				break;
			default:
				break;
			}
		}
		logger.debug("处理节点属性信息结束"+workId);
	}

	private void finishWorkEqpt(long workId) {
		logger.debug("处理节点设备信息开始"+workId);
		List<WorkNodeEqpt> workNodeEqpts = workNodeEqptService.getNodeEqptsByWorkId(workId);
		for (WorkNodeEqpt workNodeEqpt : workNodeEqpts) {
			BsNodeEqpt eqpt = new BsNodeEqpt();
			BeanUtils.copyProperties(workNodeEqpt, eqpt);
			switch (workNodeEqpt.getModifyTag()) {
			case Constant.ADD:
				bsNodeEqptService.insertNodeEqpt(eqpt);
				break;
			case Constant.UPDATE:
				bsNodeEqptService.updateNodeEqpt(eqpt);
				break;
			case Constant.DEL:
				bsNodeEqptService.updateNodeEqpt(eqpt);
				break;
			default:
				break;
			}
		}
		logger.debug("处理节点设备信息结束"+workId);
	}

	private void finishWorkNodeNetAccess(long workId) {
		logger.debug("处理节点接入信息开始"+workId);
		List<WorkNodeNetAccess> workNodeNetAccesses = workNodeNetAccessService.getNodeIntersByWorkId(workId);
		for (WorkNodeNetAccess workNodeNetAccess : workNodeNetAccesses) {
			BsNodeNetAccess netAccess = new BsNodeNetAccess();
			BeanUtils.copyProperties(workNodeNetAccess, netAccess);
			switch (workNodeNetAccess.getModifyTag()) {
			case Constant.ADD:
				bsNodeNetAccessService.insertNetAccess(netAccess);
				break;
			case Constant.UPDATE:
				bsNodeNetAccessService.updateNetAccess(netAccess);
				break;
			case Constant.DEL:
				bsNodeNetAccessService.updateNetAccess(netAccess);
				break;

			default:
				break;
			}
		}
		logger.debug("处理节点接入信息结束"+workId);
	}

	private void finishWorkNode(Work work) {
		logger.debug("处理节点信息开始"+work.getWorkId());
		List<WorkNode> workNodes = workNodeService.getNodesByWorkId(work.getWorkId());
		for (WorkNode workNode : workNodes) {
			BsNode node = new BsNode();
			BeanUtils.copyProperties(workNode, node);
			switch (workNode.getModifyTag()) {
			case Constant.ADD:
				//node.setProdInstId(work.getProdInstId());
				bsNodeService.insertNode(node);
				break;
			case Constant.UPDATE:
				//node.setProdInstId(work.getProdInstId());
				bsNodeService.updateNode(node);
				break;
			case Constant.DEL:
				//node.setProdInstId(work.getProdInstId());
				bsNodeService.updateNode(node);
				break;
			default:
				break;
			}
		}
		logger.debug("处理节点信息结束"+work.getWorkId());
	}

	private void finishOrderContract(Long orderId) {
		logger.debug("处理合同信息开始"+orderId);
		List<OrderContract> orderContrcts = orderContractService.getByOrderId(orderId);
		logger.info("订单合同信息："+JSON.parse(JSON.toJSONString(orderContrcts)));
		for (OrderContract orderContract : orderContrcts) {
			BsContract contract = new BsContract();
			BeanUtils.copyProperties(orderContract, contract);
			switch (orderContract.getModifyTag()) {
			case Constant.ADD:
				contract.setState(Constant.CONTRACT_STATE_NORMAL);
				bsContractService.insertContract(contract);
				break;
			case Constant.UPDATE:
				bsContractService.updateContract(contract);
				break;
			case Constant.DEL:
				contract.setState(Constant.CONTRACT_STATE_DELETE);
				bsContractService.updateContract(contract);
				break;
			default:
				break;
			}
		}
		logger.debug("处理合同信息开始"+orderId);
		
	}

	private void finishOrderProduct(Long orderId) {
		logger.debug("处理产品信息开始"+orderId);
		List<OrderProduct> orderProducts = orderProductService.getByOrderId(orderId);
		for (OrderProduct orderProduct : orderProducts) {
			BsProduct product = new BsProduct();
			BeanUtils.copyProperties(orderProduct, product);
			switch (orderProduct.getModifyTag()) {
			case Constant.ADD:
				bsProductService.insertBsProduct(product);
				break;
			case Constant.UPDATE:
				bsProductService.updateBsProduct(product);
				break;
			case Constant.DEL:
				bsProductService.updateBsProduct(product);
				break;
			default:
				break;
			}
			finishAttr(product.getProdInstId(), Constant.ATTR_TYPE_PROD);
		}
		logger.debug("处理产品信息结束"+orderId);
	}

	@SuppressWarnings("unused")
	private void finishOrderProject(Long orderId) {
		logger.debug("处理项目信息开始"+orderId);
		List<OrderProject> orderProjects=orderProjectService.getByOrderId(orderId);
		for (OrderProject orderProject : orderProjects) {
			BsProject project = new BsProject();
			BeanUtils.copyProperties(orderProject, project);
			switch (orderProject.getModifyTag()) {
			case Constant.ADD://新增
				project.setState(Constant.PROJECT_STATE_NORMAL);
				bsProjectService.insertBsProject(project);
				break;
			case Constant.UPDATE://修改
				bsProjectService.updateBsProject(project);
				break;
			case Constant.DEL://删除
				project.setState(Constant.PROJECT_STATE_DELETE);
				bsProjectService.updateBsProject(project);
				break;
			default:
				break;
			}
		}
		logger.debug("处理项目信息结束"+orderId);
	}

	private void finishOrderCust(Long orderId) {
		logger.debug("处理客户信息开始"+orderId);
		// 获取订单客户信息
		List<OrderCustomer> orderCustomers=custService.getByOrderId(orderId);
		for (OrderCustomer orderCustomer : orderCustomers) {
			BsCust cust = new BsCust();
			BeanUtils.copyProperties(orderCustomer, cust);
			switch (orderCustomer.getModifyTag()) {
			case Constant.ADD://新增(需判断是否已存在客户)
				bsCustService.insertBsCust(cust);
				break;
			case Constant.UPDATE://修改
				bsCustService.updateBsCust(cust);
				break;
			case Constant.DEL://删除（更新客户状态）
				cust.setCustState(Constant.CUST_STATE_DELETE);
				bsCustService.updateBsCust(cust);
				break;
			default:
				break;
			}
			//记录客户属性信息
			finishAttr(cust.getCustId(), Constant.ATTR_TYPE_CUST);
		}
		logger.debug("处理客户信息结束"+orderId);
	}
	
	private void finishOrderAccount(Long orderId) {
		logger.debug("处理账户信息开始"+orderId);
		List<OrderAccount> orderAccounts = orderAcctService.getByOrderId(orderId);
		for (OrderAccount orderAccount : orderAccounts) {
			BsAccount bsAcct = new BsAccount();
			BeanUtils.copyProperties(orderAccount, bsAcct);
			switch (orderAccount.getModifyTag()) {
			case Constant.ADD:// 新增
				bsAcct.setAcctState(Constant.ACCT_STATE_NORMAL);
				bsAcctService.insertBsAcct(bsAcct);
				break;
			case Constant.UPDATE:// 修改
				bsAcctService.updateBsAcct(bsAcct);
				break;
			case Constant.DEL:// 删除
				bsAcct.setAcctState(Constant.ACCT_STATE_DELETE);
				if(bsAcct.getDestoryTime()==null)
					bsAcct.setDestoryTime(bsAcct.getUpdateTime());
				bsAcctService.updateBsAcct(bsAcct);
				break;
			default:
				break;
			}
		}
		logger.debug("处理账户信息结束"+orderId);
	}

	private void finishOrderDiscntFee(Long orderId) {
		logger.debug("处理套餐费用信息开始"+orderId);
		List<OrderDiscntFee> orderDiscnts = orderDiscntFeeService.getByOrderId(orderId);
		for (OrderDiscntFee orderDiscntFee : orderDiscnts) {
			BsDiscntFee bsDiscntFee = new BsDiscntFee();
			BeanUtils.copyProperties(orderDiscntFee, bsDiscntFee);
			switch (orderDiscntFee.getModifyTag()) {
				case Constant.ADD:
					bsDiscntFeeService.insertBsDiscntFee(bsDiscntFee);
					break;
				case Constant.UPDATE:
					bsDiscntFeeService.updateBsDiscntFee(bsDiscntFee);
					break;
				case Constant.DEL:
					bsDiscntFeeService.updateBsDiscntFee(bsDiscntFee);
					break;
				default:
					break;
			}
		}
		logger.debug("处理套餐费用信息结束"+orderId);
	}

	private void finishPublicCloudSeg(Long workId) {
		logger.debug("处理公有云网段信息开始"+workId);
		List<WorkNodeCloudIpseg> workNodeCloudIpsegs = workNodePublicCloudSegService.getWorkCloudSegByWorkID(workId);
		for (WorkNodeCloudIpseg workNodeCloudIpseg : workNodeCloudIpsegs) {
			BsCloudIpseg bsCloudIpseg = new BsCloudIpseg();
			BeanUtils.copyProperties(workNodeCloudIpseg, bsCloudIpseg);
			switch (workNodeCloudIpseg.getModifyTag()) {
				case Constant.ADD:
					bsPublicCloudSegService.insertNodeCloudSeg(bsCloudIpseg);
					break;
				case Constant.UPDATE:
					bsPublicCloudSegService.updateNodeCloudSeg(bsCloudIpseg);
					break;
				case Constant.DEL:
					bsPublicCloudSegService.updateNodeCloudSeg(bsCloudIpseg);
					break;
				default:
					break;
			}
		}
		logger.debug("处理公有云网段信息开始"+workId);
	}
		
}
